/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.setup.trac.service;

import com.setup.trac.pojo.Evento;
import com.setup.trac.pojo.Progetti;
import com.setup.trac.pojo.StoricoTicket;
import com.setup.trac.pojo.wrappers.StatiView;
import com.setup.trac.pojo.wrappers.TicketView;
import com.setup.trac.dao.DAOService;
import com.setup.trac.pojo.Allegati;
import com.setup.trac.pojo.Profilo;
import com.setup.trac.pojo.Stati;
import com.setup.trac.pojo.Tickets;
import com.setup.trac.pojo.Utenti;
import com.setup.trac.pojo.wrappers.UtentiView;
import com.setup.trac.util.SQLCondition;
import com.setup.trac.util.TracSetupUtil;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.ResultTransformer;
import org.springframework.orm.hibernate3.HibernateTemplate;

/**
 * 
 * @author edoardo
 */
public class SearchService {

	private HibernateTemplate hibernateTemplate;
	private DAOService daoService;
	private TracSetupUtil tracSetupUtil;

	public TicketView[] convertToTicketsView(Tickets[] t) {
		TicketView[] result = new TicketView[t.length];
		for (int i = 0; i < t.length; i++) {
			Tickets tickets = t[i];
			result[i] = new TicketView();
			result[i].setTickets(tracSetupUtil.copyPojoProperties(tickets));
		}
		return result;
	}

	public TicketView[] findTicketsByStato(TicketView ticketView) {
		Tickets target = new Tickets();
		target = tracSetupUtil.copyPojoProperties(ticketView.getTickets());
		DetachedCriteria criteria = DetachedCriteria.forClass(Tickets.class);

		// List<Tickets> ticketList =
		// hibernateTemplate.findByCriteria(criteria.add(Restrictions.eq("stati",
		// tickets.getStati())));
		// Tickets[] ticketsArray = ticketList.toArray(new Tickets[0]);
		Tickets[] ticketsArray = daoService.findByCriteria(new Tickets[0],
				Restrictions.eq("stati", target.getStati()), Tickets.class);
		TicketView[] tv = new TicketView[ticketsArray.length];
		for (int i = 0; i < ticketsArray.length; i++) {
			Tickets t = ticketsArray[i];
			tv[i] = new TicketView();
			tv[i].setTickets(tracSetupUtil.copyPojoProperties(t));

		}
		return tv;
	}

	public Profilo findProfiloByDescrizione(String descrizione) {
		Criterion c = Restrictions.eq("descrizione", descrizione);
		Profilo[] p = daoService.findByCriteria(new Profilo[0], c,
				Profilo.class);

		return tracSetupUtil.copyPojoProperties(p[0]);
	}

	public UtentiView[] findUtentiAbilitatiProgettoByProfilo(String idProgetto,
			Profilo profilo) {
		Criterion cProgetto = Restrictions.eq("idProgetto", new BigDecimal(
				idProgetto));

		Progetti[] p = daoService.findByCriteria(new Progetti[0], cProgetto,
				Progetti.class);
		Progetti pPurged = tracSetupUtil.copyPojoProperties(p[0]);

		Set<Utenti> utentis = new HashSet<Utenti>();
		Iterator<Utenti> it = pPurged.getUtentis().iterator();
		for (; it.hasNext();) {
			Utenti utenti = it.next();
			if (utenti.getProfilo().getIdProfilo().equals(
					profilo.getIdProfilo())) {
				utentis.add(utenti);
			}
		}
		pPurged.setUtentis(utentis);
		Utenti[] u = (Utenti[]) pPurged.getUtentis().toArray(new Utenti[0]);
		UtentiView[] result = new UtentiView[u.length];
		for (int i = 0; i < u.length; i++) {
			Utenti utenti = u[i];
			result[i] = new UtentiView();
			result[i].setUtenti(tracSetupUtil.copyPojoProperties(utenti));
		}
		return result;
	}

	public Utenti findUtenteById(String idUtente) {
		return tracSetupUtil.copyPojoProperties(daoService.findByPK(
				Utenti.class, new BigDecimal(idUtente)));
	}

	public UtentiView findUtente(String username, String md5) {
		Utenti utente = new Utenti();
		Criterion usernameCriterion = Restrictions.eq("username", username);
		Criterion passwordCriterion = Restrictions.eq("password", md5);
		Utenti[] u = daoService.findByCriteria(new Utenti[0], Restrictions.and(
				usernameCriterion, passwordCriterion), Utenti.class);
		// non faccio controlli se trovo o no record dato che viene fatto già
		// nel validator del login
		UtentiView result = new UtentiView();
		Utenti utentiWrapped = result.getUtenti();
		result.setUtenti(tracSetupUtil.copyPojoProperties(u[0]));
		return result;
	}

	// public UtenteProgettoView[] findProgettiByUtente(Utenti u){
	//
	// }

	public UtentiView findUtenteByUsername(String username)
			throws UserNotFoundException {
		Utenti utente = new Utenti();
		Utenti[] u = daoService.findByCriteria(new Utenti[0], Restrictions.eq(
				"username", username), Utenti.class);
		if (u == null || u.length == 0) {
			throw new UserNotFoundException("Utente inesistente");
		}
		UtentiView result = new UtentiView();
		result.setUtenti(tracSetupUtil.copyPojoProperties(u[0]));
		return result;
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public DAOService getDaoService() {
		return daoService;
	}

	public void setDaoService(DAOService daoService) {
		this.daoService = daoService;
	}

	public TracSetupUtil getTracSetupUtil() {
		return tracSetupUtil;
	}

	public void setTracSetupUtil(TracSetupUtil tracSetupUtil) {
		this.tracSetupUtil = tracSetupUtil;
	}

	/**
	 * Prende l'elenco completo dei tickets senza filtrare. Usato da utente
	 * amministratore
	 * 
	 * @return
	 */
	public TicketView[] findTickets() {
		Tickets[] t = daoService.findAll(new Tickets[0], Tickets.class);
		TicketView[] result = convertToTicketsView(t);
		return result;
	}

	public TicketView[] findTickets(int firstResult) {
		Tickets[] t = daoService.findAll(new Tickets[0], Tickets.class,
				firstResult);
		TicketView[] result = convertToTicketsView(t);
		return result;
	}

	public <T> T[] find(T[] t, SQLCondition sqlCondition, Class aClass) {
		if (sqlCondition != null) {
			t = daoService.findByCriteria(t, sqlCondition.create(), aClass);
			for (int i = 0; i < t.length; i++) {

				t[i] = tracSetupUtil.copyPojoProperties(t[i]);
			}
		}else{
			t = daoService.findAll(t, aClass);
		}
		return t;
	}
	public <T> T[] find(T[] t, Class aClass) {
		return find(t, null, aClass);
	}
	
public <T> T[] find(T[] t, String queryString, final ResultTransformer transformer,Object... paramsValues) {
		
		return  daoService.find(t, queryString, transformer,paramsValues);
	}
	
	
	/**
	 * trova tutti i ticket che soddisfano la lista di parametri in input
	 * 
	 * @param params
	 * @return
	 */
	public TicketView[] findTickets(SQLCondition cc) {
		Criterion criterion = cc.create();
		Tickets[] t = daoService.findByCriteria(new Tickets[0], criterion,
				Tickets.class);
		return convertToTicketsView(t);
	}

	public Object count(Class<?> aClass, SQLCondition cc) {
		return daoService.count((cc==null?null:cc.create()), aClass);
	}
	
	public Object count(Class<?> aClass){
		return count(aClass,null);
	}

	
	public <T> T[] find(T[] t,SQLCondition cc,int firstResult, Class<?> aClass){
		Criterion criterion = null;
		if(cc!=null){
			criterion=cc.create();
		}
		T[] result = daoService.findByCriteria(t, criterion, aClass, firstResult);
		for (int i = 0; i < result.length; i++) {
			T source = result[i];
			
			source = tracSetupUtil.copyPojoProperties(source);
			result[i]=source;
		}
		return result;
	}
	
	public TicketView[] findTickets(SQLCondition cc, int firstResult) {
		Criterion criterion = cc.create();
		Tickets[] t = daoService.findByCriteria(new Tickets[0], criterion,
				Tickets.class, firstResult);
		return convertToTicketsView(t);
	}

	public Progetti findProgettoByTicket(String idTicket) {
		Tickets t = new Tickets();
		t.setIdTicket(new BigDecimal(idTicket));
		Criterion cr = Restrictions.eq("idTicket", new BigDecimal(idTicket));
		Tickets[] tickets = daoService.findByCriteria(new Tickets[0], cr,
				Tickets.class);
		if (tickets != null && tickets.length > 0) {
			Progetti progetto = new Progetti();
			progetto.setIdProgetto(tickets[0].getIdProgetto());
			cr = Restrictions.eq("idProgetto", progetto.getIdProgetto());
			Progetti[] p = daoService.findByCriteria(new Progetti[0], cr,
					Progetti.class);
			if (p != null && p.length > 0) {
				return p[0];
			}
		}
		return null;
	}

	public StatiView[] findAllStati() {
		Stati[] s = daoService.findAll(new Stati[0], Stati.class);
		StatiView[] sv = new StatiView[s.length];
		for (int i = 0; i < s.length; i++) {
			Stati stati = s[i];
			sv[i] = new StatiView();
			Stati _copiaStato = tracSetupUtil.copyPojoProperties(stati);
			sv[i].setStati(_copiaStato);
		}
		return sv;
	}

	public Evento[] findEventiDaInviare() {
		Criterion c = Restrictions.eq("inviato", "0");
		Evento[] result = daoService.findByCriteria(new Evento[0], c,
				Evento.class);
		for (int i = 0; i < result.length; i++) {
			Evento evento = result[i];
			result[i] = tracSetupUtil.copyPojoProperties(evento);
		}
		return result;

	}

	public StoricoTicket[] findMaxStoricoTicketByTicket(StoricoTicket[] t,
			Tickets ticket) {
		return tracSetupUtil.copyPojoProperties(getDaoService()
				.findByNamedQuery(t, "GET_LAST_STORICO", ticket.getIdTicket()));
	}

	public Progetti findProgettoById(String idProgetto) {
		Criterion c = Restrictions.eq("idProgetto", new BigDecimal(idProgetto));
		Progetti[] result = daoService.findByCriteria(new Progetti[0], c,
				Progetti.class);
		return result[0];
	}


	public <T> T[] find(T[] t, int firstRecord,
			Class<?> aClass) {
		return find(t, null, firstRecord, aClass);
	}

	public int getMaxResults() {
		return getDaoService().getMaxResults(); 
	}


}
